package practicalWork;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import subjectAndProfessorship.EnrolledInProfessorship;
import subjectAndProfessorship.Professorship;
import util.MyDate;

/**
 * @author Nati
 * @autor: Medici Maria Laura
 */
public class PracticalWork {
	/* ******************************** Variables ******************************** */
	private String name;
	private List <ThemeContent> temasConContenidos = new ArrayList <ThemeContent>(); 
	private List <ToHandIn> entregas = new ArrayList<ToHandIn>();
	private MyDate submiteDate;
	private Professorship catedra;
	
	/* ******************************* Constructor ******************************* */
	public PracticalWork(String name,MyDate submiteDate,Professorship catedra){
		this.name = name; 
		this.submiteDate = submiteDate; 
		this.catedra = catedra;
	}
	
	/* ******************************** Get & Set ******************************** */
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public void setTemasConContenidos(List <ThemeContent> temasConContenidos) {
		this.temasConContenidos = temasConContenidos;
	}
	public List <ThemeContent> getTemasConContenidos() {
		return this.temasConContenidos;
	}
	public void setEntregas(List <ToHandIn> entregas) {
		this.entregas = entregas;
	}
	public List <ToHandIn> getEntregas() {
		return entregas;
	}
	public void setSubmiteDate(MyDate submiteDate) {
		this.submiteDate = submiteDate;
	}
	public MyDate getSubmiteDate() {
		return submiteDate;
	}
	
	public void setCatedra(Professorship catedra) {
		this.catedra = catedra;
	}

	public Professorship getCatedra() {
		return catedra;
	}

	/* ********************************* Metodos ********************************* */		
	public void addTheme(ThemeContent tema){
		//agrega un tema con contenidos al trabajo practico
		this.getTemasConContenidos().add(tema);
	}
	
	public void addHandIn(ToHandIn entrega){
		//agrega una entrega al trabajo practico
		this.getEntregas().add(entrega);
	}
	
	/**
	 * De un Tp devuelve la mejor nota de todas sus entregas,si las notas de ambas entregas son iguales, compara por la fechas de entregas,
	 * si las fechas de entrega son iguales, compara por apellidos,si el apellido de un alumno es menor que la de otro alumno
	 */
	public int bestScoreIn() {
		ToHandIn maxEntrega = this.getEntregas().remove(0);
		
		for(ToHandIn entrega :this.getEntregas()){
			if(maxEntrega.getNota() == entrega.getNota()){//si las notas de ambas entregas son iguales, compara por fechas de entregas
				if(entrega.getRealSubmiteDate().equals(maxEntrega.getRealSubmiteDate())){//si las fechas de entrega son iguales, compara por los apellidos de los alumnos
					if( entrega.apellido().compareTo(maxEntrega.apellido()) < 0 )// si el apellido del alumno es menor que la de otro alumno
						maxEntrega = entrega;
				} else {
					if (entrega.getRealSubmiteDate().esAnterior(maxEntrega.getRealSubmiteDate())) //si una entrega es posterior a otra
						maxEntrega = entrega;
				}
			} else{
				if(maxEntrega.getNota() < entrega.getNota())//si la nota de una entrega es menor a otra
					maxEntrega = entrega;
			}
		}
		return maxEntrega.getNota(); 
	}

	/**
	 * Devuelve el alumno con mejor nota,si las notas de ambas entregas son iguales, compara por la fechas de entregas,
	 * si las fechas de entrega son iguales, compara por apellidos,si el apellido de un alumno es menor que la de otro alumno
	 */
    public EnrolledInProfessorship alumnoConMejorNota(){
		ToHandIn maxEntrega = this.getEntregas().remove(0);
		for(ToHandIn entrega :this.getEntregas()){	
			if(maxEntrega.getNota() == entrega.getNota()){//si las notas de ambas entregas son iguales, compara por la fechas de entregas
				if(entrega.getRealSubmiteDate().equals(maxEntrega.getRealSubmiteDate())){//si las fechas de entrega son iguales, compara por apellidos
					if(  entrega.apellido().compareTo(maxEntrega.apellido()) < 0 )// si el apellido de un alumno es menor que la de otro alumno
						maxEntrega = entrega;
				}else {
					if(entrega.getRealSubmiteDate().esAnterior(maxEntrega.getRealSubmiteDate()))//si una entrega es posterior a otra					
					    maxEntrega = entrega;
				}
			}else{
		    	if(maxEntrega.getNota() < entrega.getNota())//si la nota de una entrega es menor a otra 
			    	 maxEntrega = entrega;
			}
		}
		return maxEntrega.takeAlumnoRepresentante();	
    } 

    
    public List<EnrolledInProfessorship> alumnosQueAprobaronUnTema (ThemeContent tema){
    	List<EnrolledInProfessorship> aprobaronTema= new LinkedList<EnrolledInProfessorship>(); 
    	for (ToHandIn entregas: this.entregas){
    		if (entregas.getNota()>6)
    			aprobaronTema.addAll(entregas.makeListAlumno()); 
    	}
    	return aprobaronTema; 
    }
    
    /**
     * Devuelve la nota de un trabajo practico de un alumno
     * @param alumno
     */
    public int notaDeUnAlumno(EnrolledInProfessorship alumno) {
		int nota =0;
		for(ToHandIn entrega :this.getEntregas()){
			if(entrega.perteneceAlumno(alumno)){
			   nota = entrega.getNota();
			}
		}
		return nota;
	}

    /**
     * Devuelve los alumnos que entregaron un trabajo practico
     */
	public List<EnrolledInProfessorship> alumnosQueEntregaron() {	
		List<EnrolledInProfessorship> alumnos = this.getCatedra().getAlumnosInscriptos();
	    alumnos.removeAll(this.obtenerAlumnosDeLasEntregas());	
		return alumnos;
	}
		
	/**
	 * Crea una lista con los alumnos de todas las entregas de un Trabajo practico
	 */
	public List<EnrolledInProfessorship> obtenerAlumnosDeLasEntregas(){
		List<EnrolledInProfessorship> students = new ArrayList<EnrolledInProfessorship>();
		for(ToHandIn entrega :this.getEntregas()){
			students.addAll(entrega.makeListAlumno());	
		}
		return students;	
	}
	
	/**
	 * Devuelve los temas te un trabajo practico
	 */
	public List<ThemeContent> themes(){
		return this.getTemasConContenidos();
	}

	/**
	 * Saca a los alumnos que no pueden hacer un trabajo practico debido a su regularidad
	 */
	public void sacarAlumnosDebidoRegularidad(){
		for(ToHandIn entrega :this.getEntregas()){
			 entrega.removerAlumnos(this.getCatedra());//remueve alumnos que no pueden rendir tp
		}	
	}
	
	/**
	 * Remueve las entregas que no tenga alumnos
	 */
	public void eliminarEntregasVacias() {
		List<ToHandIn> aceptables = new ArrayList<ToHandIn>();
		for(ToHandIn entrega :this.getEntregas()){
			if(! entrega.vacia()){
				aceptables.add(entrega);
			}
		}
		this.setEntregas(aceptables);
	}
}
